/'''
 ' @brief EventManager sequence diagrams.
 ' @see https://plantuml.com/guide
 '/
@startuml
!pragma teoz true
!theme amiga
/' allowmixing '/
hide empty members

!theme amiga
mainframe  How to use the API
control Engine
actor User
participant EventManager

== <b>setup</b> ==

User -> EventManager : addListener ()
activate EventManager
User <-- EventManager : <i>listenerID = 1</i>
deactivate EventManager
note right
    You can have as many listeners as you need.
    Most will need just one though, for regular events being handled
       synchronously with the game loop;
end note
User -> EventManager : addListener (<i>async_callback</i>)
activate EventManager
User <-- EventManager : <i>listenerID = 2</i>
deactivate EventManager
note right
    And some may require two.
    The second to be a "high priority" handler that will be notified of
       events in real time with a callback.
end note

||||
note over User, EventManager
    After getting an ID, you can start registering to listem for specific events.
end note
||||

User -> EventManager : listenForQuitEvent (2)
activate EventManager
User <-- EventManager
deactivate EventManager
note right
    This call would create an entry to forward the OS generated <b>Quit</b> event.
    (which is already maped by the ArcadeFighter initialization process)
end note

||||
User -> EventManager : listenForEvent (1, <i>key_state::UP, SDL_SCANCODE_W</i>)
activate EventManager
User <-- EventManager : <i>EventManager::event_s</i>
deactivate EventManager
note right
    This call would listen for when the W key is released in the keyboard.
    The returned structure can be used to compare to incoming events in the
       user's event handle method.
end note


== <b>game starts</b> ==

== <b>asynchronous sequence</b> ==
EventManager -> EventManager : working_thread ()
activate EventManager
EventManager -> EventManager : <<check for all known event sources>>
EventManager -> EventManager
note right
    Check all the registered listeners for
    someone interested in this event...

    Most events will be queued for synchronous retrieval.
    Some listeners require real time event notification...
end note
activate EventManager
EventManager -> User : <i>async_callback (EventManager::event_s)</i>
activate User
User --> EventManager
deactivate User
deactivate EventManager
note over User, EventManager
    The thread will be blocked until the User call returns!!!
end note
deactivate EventManager

== <b>synchronous sequence</b> ==
Engine -> Engine : GameLoop ()
activate Engine
Engine -> EventManager : update ()
EventManager --> Engine
note right
    SDL (the base API) requires a single contact point per loop to build
       the event queue ALL the OS sources capable of generating events.
    Most of our events are sorted asynchronously as they become available...
end note
Engine -> User : event_handler ()
activate Engine
activate User
User -> EventManager : pop (<i>listenerID</i>)
activate EventManager
EventManager --> User : <i>EventManager::event_s</i>
deactivate EventManager
note over User : Repeat until queue is empty.
User --> Engine
deactivate User
deactivate Engine
note over Engine : Call every other event handler...
deactivate Engine

@enduml
